package unite;


import java.io.Serializable;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import affichage.FinPartieView;

import deroulementjeu.Equipe;
import deroulementjeu.TypeEquipe;

import terrain.CaseTerrain;


/**
 * Décrit les Pokémon qui attaquent à distance
 * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
 *
 */
public class Distance extends Pokemon implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * Constructeur d'une unité de type attaque à distance
     * @param caseTerrain CaseTerrain sur laquelle sera placée l'unité créée
     */
    public Distance(CaseTerrain caseTerrain, Equipe equipe) {
        this.deplacementPostMortem = -1;
        this.equipe = equipe;
        equipe.ajouterUnite(this);
        this.caseTerrain = caseTerrain;
        caseTerrain.ajouterUnite(this);
        this.pv = this.getRegles().getCaracUnite(TypeUnite.ELECTRIQUE,
                TypeCarac.PV);
        this.deplacement = this.getRegles().getCaracUnite(TypeUnite.ELECTRIQUE,
                TypeCarac.DEPLACEMENT);
        this.xp = 1;
        this.chance = initChance();
        this.deplacementPostMortem = this.getRegles().getDepPostMortem();
    }
	
    /**
     * Renvoie le type du Pokémon attaquant à distance.
     * @return type
     */
    @Override
    public TypeUnite getType() {
        return TypeUnite.ELECTRIQUE;
    }
	
    /**
     * Cette fonction gère un combat à distance, c'est-à-dire une attaque ponctuelle
     * sans riposte
     * @param attaque l'unité à attaquer à distance
     * @return vrai si l'unité attaquée est tuée à la fin de l'assaut
     */
    public boolean combatDistance(Unite attaque) {
        if (attaque.getCaseTerrain().coutDAccesVolDOiseau(this.getCaseTerrain())
                <= this.getVision()) {
            this.setDeplacement(0);
            int pertePV = this.lanceCoup(attaque);
			
            if (attaque.mort()) {
                Pokemon pok = (Pokemon) this;
                int gainXP = pok.gainXP(attaque);

                attaque.getCaseTerrain().retirerUnite();
                if (this.getEquipe().getType() == TypeEquipe.HUMAIN) {
                    JOptionPane.showMessageDialog(null,
                            "Votre unité a attaqué une unité ennemie à distance.\nVotre unité a infligé "
                            + pertePV
                            + " points de dégâts.\nL'unité ennemie est morte, votre unité a gagné "
                            + gainXP + " XP.",
                            "Information",
                            JOptionPane.INFORMATION_MESSAGE);
                } else {
                    JOptionPane.showMessageDialog(null,
                            "Une unité ennemie a attaqué votre unité à distance.\nElle a infligé "
                            + pertePV
                            + " points de dégâts.\nVotre unité est morte, l'unité ennemie a gagné "
                            + gainXP + " XP.",
                            "Information",
                            JOptionPane.INFORMATION_MESSAGE);
                }
                if (this.equipe.getPartie().finDePartie() != null) {
                    new FinPartieView(this.equipe.getPartie(),
                            this.equipe.getPartie().finDePartie().getEnnemi());
                }
                return true;
            } else if (this.getEquipe().getType() == TypeEquipe.HUMAIN) {
                JOptionPane.showMessageDialog(null,
                        "Votre unité a attaqué une unité ennemie.\nVotre unité a infligé "
                        + pertePV + " points de dégâts.",
                        "Information",
                        JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(null,
                        "Une unité ennemie  a attaqué votre unité.\nElle a infligé "
                        + pertePV + " points de dégâts.",
                        "Information",
                        JOptionPane.INFORMATION_MESSAGE);
            }
            return false;
        }
        return false;
    }
	
    /**
     * Méthode qui permet d'accéder à la liste des cases contenant des pokémons attaquables à distance.
     * @return Collection des caseTerrain attaquables.
     */
    public ArrayList<CaseTerrain> getListeCasesTerrainAttaquables() {
        ArrayList<CaseTerrain> ret = new ArrayList<CaseTerrain>();

        ret.add(this.getCaseTerrain());
        ret = getEquipe().getCasesAffichables(ret, getVision());
        ret.retainAll(getEquipe().getEnnemi().getCasesUnites());
		
        return ret;
    }
}
